import math


class GlobalGRS:
    def UnitsPerPixel(self, width, zoom):
        """
        计算瓦片的分辨率

        Args:
            width (int): 瓦片大小
            zoom (int): 地图层级

        Returns:
            float: 瓦片分辨率
        """
        return 180.0 / width / 2**zoom

    def WmtsTileToLonLat(self, column, row, zoom):
        """
        WMTS瓦片转左上角经纬度
        Args:
            column (int): 列序列号(x序列),
            row (int): 列序行号(y序列)
            zoom (int): 地图层级

        Returns:
            左上角经度lon, 左上角纬度lat
        """
        # 左上角经度
        lon = (column * 180.0) / 2**zoom - 180.0
        # 左上角纬度
        lat = (row * 180.0) / 2**zoom - 90.0
        return lon, -lat

    def LonLatToWmtsTile(self, lon, lat, zoom):
        """
        经纬度转WMTS瓦片
        Args:
            lon (float): 经度
            lat (float): 纬度
            zoom (int): 地图层级

        Returns:
            列号(x序列), 行号(y序列)
        """
        # 瓦片列号(x序列)
        col = int(math.floor((lon + 180.0) / 180.0 * math.pow(2, zoom)))
        # 瓦片行号(y序列)
        row = int(math.floor((-lat + 90) / 180.0 * math.pow(2, zoom)))
        return col, row

    def WmtsTileToZoom(self, width, imageWidth, maxX, minX):
        """
        获取瓦片地图层级

        Args:
            width (int): 瓦片大小
            imageWidth (int): 地图视窗宽度
            maxX (float): 最大经度
            minX (float): 最小纬度

        Returns:
            int: 地图层级
        """
        return int(math.ceil(math.log(180.0 * imageWidth / width / (maxX - minX), 2)))

    def TmsTileToLonLat(self, column, row, zoom):
        """
        获取TMS服务瓦片左下角经纬度

        Args:
            column (int): 列序号(x序列)
            row (int): 行号(y序列)
            zoom (int): 地图层级

        Returns:
            经度lon, 纬度lat
        """
        # 左下角经度
        lon = (column * 180.0) / 2**zoom - 180.0
        # 左下角经度
        lat = (row * 180) / 2**zoom - 90.0
        return lon, lat

    def LonLatToTmsTile(self, lon, lat, zoom):
        """
        经纬度转TMS服务瓦片行列号

        Args:
            lon (float): 经度
            lat (float): 纬度
            zoom (int): 地图层级

        Returns:
            列序号(x序列), 行序号(y序列)
        """
        col = int(math.floor((lon + 180.0) / 180.0 * math.pow(2, zoom)))
        row = int(math.floor((lat + 90) / 180.0 * math.pow(2, zoom)))
        return col, row

    def TmsTileToZoom(self, width, imageWidth, maxX, minX):
        """
        获取TMS服务地图层级

        Args:
            width (int): 瓦片大小
            imageWidth (int): 地图视窗宽度
            maxX (float): 最大经度
            minX (float): 最小纬度

        Returns:
            int: 地图层级
        """
        return int(math.ceil(math.log(180.0 * imageWidth / width / (maxX - minX), 2)))


class LatLngInfo:
    def __init__(self, lat, lng):
        self.Lat = lat
        self.Lng = lng


class TileIndexInfo:
    def __init__(self, column, row):
        self.Column = column
        self.Row = row

    def __str__(self):
        return f"{self.Column},{self.Row}"


if __name__ == "__main__":
    lon = 116.400451
    lat = 39.915351
    zoom = 13
    grs = GlobalGRS()
    tx, ty = grs.LonLatToTmsTile(lon, lat, zoom)
    wx, wy = grs.LonLatToWmtsTile(lon, lat, zoom)

    tx = str(tx)
    ty = str(ty)
    wx = str(wx)
    wy = str(wy)
    zoomStr = str(zoom)

    print("z/col/row", zoom, wx, wy)

    print("https://t2.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL=" +
          wx + "&TILEROW=" + wy + "&TILEMATRIX=" + str(zoom+1) + "&tk=92c2ba98e695eb63048b3df93a9ad732")

    # {IpServer}是geoserver所在服务器ip+port
    print("http://{IpServer}/geoserver/gwc/service/wmts/rest/guangxi:img_c/raster/EPSG:4326/EPSG:4326:" +
          zoomStr + "/" + wx + "/" + wy + "?format=image/png")

    print("http://{IpServer}/geoserver/gwc/service/tms/1.0.0/guangxi%3Aimg_c@EPSG%3A4326@png/"
          + zoomStr + "/" + tx + "/" + ty + ".png")
